import { ref, type Ref } from 'vue'
import { getSysDictByTypeApi, type SysDict } from '@/api/system/dict'

// 字典缓存，避免重复请求
const dictCache = new Map<string, SysDict[]>()

/**
 * 获取字典数据并返回响应式引用
 * @param dictTypeCode 字典类型编码
 * @param useCache 是否使用缓存，默认true
 * @returns 响应式的字典数据引用
 */
export function useDict(dictTypeCode: string, useCache: boolean = true): Ref<SysDict[]> {
  const dictData = ref<SysDict[]>([])

  // 如果使用缓存且缓存中存在数据，直接返回
  if (useCache && dictCache.has(dictTypeCode)) {
    dictData.value = dictCache.get(dictTypeCode)!
    return dictData
  }

  // 加载字典数据
  const loadDict = async () => {
    try {
      const res = await getSysDictByTypeApi(dictTypeCode)
      const data = res.data || []
      dictData.value = data

      // 缓存数据
      if (useCache) {
        dictCache.set(dictTypeCode, data)
      }
    } catch (error) {
      console.error(`加载字典数据失败 [${dictTypeCode}]:`, error)
      dictData.value = []
    }
  }

  // 立即加载数据
  loadDict()

  return dictData
}

/**
 * 获取字典数据（非响应式）
 * @param dictTypeCode 字典类型编码
 * @param useCache 是否使用缓存，默认true
 * @returns Promise<SysDict[]>
 */
export async function getDict(dictTypeCode: string, useCache: boolean = true): Promise<SysDict[]> {
  // 如果使用缓存且缓存中存在数据，直接返回
  if (useCache && dictCache.has(dictTypeCode)) {
    return dictCache.get(dictTypeCode)!
  }

  try {
    const res = await getSysDictByTypeApi(dictTypeCode)
    const data = res.data || []

    // 缓存数据
    if (useCache) {
      dictCache.set(dictTypeCode, data)
    }

    return data
  } catch (error) {
    console.error(`加载字典数据失败 [${dictTypeCode}]:`, error)
    return []
  }
}

/**
 * 根据字典编码获取字典名称
 * @param dictTypeCode 字典类型编码
 * @param dictCode 字典编码
 * @returns 字典名称，如果未找到返回原编码
 */
export function getDictName(dictTypeCode: string, dictCode: string | undefined): string {
  if (!dictCode) return '-'

  const cachedData = dictCache.get(dictTypeCode)
  if (cachedData) {
    const item = cachedData.find((dict) => dict.dictCode === dictCode)
    return item ? item.dictName : dictCode
  }

  return dictCode
}

/**
 * 清除字典缓存
 * @param dictTypeCode 可选的字典类型编码，如果不传则清除所有缓存
 */
export function clearDictCache(dictTypeCode?: string): void {
  if (dictTypeCode) {
    dictCache.delete(dictTypeCode)
  } else {
    dictCache.clear()
  }
}

/**
 * 刷新字典数据（清除缓存并重新加载）
 * @param dictTypeCode 字典类型编码
 */
export async function refreshDict(dictTypeCode: string): Promise<SysDict[]> {
  clearDictCache(dictTypeCode)
  return await getDict(dictTypeCode, true)
}

/**
 * 批量获取多个字典类型的数据
 * @param dictTypeCodes 字典类型编码数组
 * @param useCache 是否使用缓存，默认true
 * @returns Promise<Map<string, SysDict[]>>
 */
export async function getMultipleDicts(
  dictTypeCodes: string[],
  useCache: boolean = true
): Promise<Map<string, SysDict[]>> {
  const result = new Map<string, SysDict[]>()

  // 并行加载所有字典数据
  const promises = dictTypeCodes.map(async (dictTypeCode) => {
    const data = await getDict(dictTypeCode, useCache)
    result.set(dictTypeCode, data)
  })

  await Promise.all(promises)
  return result
}

/**
 * 批量获取多个字典类型的数据并返回响应式引用
 * @param dictTypeCodes 字典类型编码数组
 * @param useCache 是否使用缓存，默认true
 * @returns Map<string, Ref<SysDict[]>>
 */
export function useMultipleDicts(
  dictTypeCodes: string[],
  useCache: boolean = true
): Map<string, Ref<SysDict[]>> {
  const result = new Map<string, Ref<SysDict[]>>()

  dictTypeCodes.forEach((dictTypeCode) => {
    result.set(dictTypeCode, useDict(dictTypeCode, useCache))
  })

  return result
}
